/*
 * @Author: BaiYu
 * @Date: 2021-03-18 19:53:14
 * @LastEditTime: 2021-04-22 10:34:18
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \STM32_Proj\Source\Dev\Motor.c
 */
#include "Motor.h"


uint16_t Buffer_DEC[20] = {15000, 15000, 20000, 20000, 25000, 25000, 30000, 30000, 35000, 35000,
                           40000, 40000, 45000, 45000, 50000, 50000, 55000, 55000, 60000, 60000};

uint16_t Buffer_INC[20] = {60000, 60000, 55000, 55000, 50000, 50000, 45000, 45000, 40000, 40000,
                           35000, 35000, 30000, 30000, 25000, 25000, 20000, 20000, 15000, 15000};

												
/**
 * @description: 步进电机控制引脚初始化 CP DIR EN 低电平有效
 * @param {*}
 * @return {*}
 */
void Motor_GPIOConfig(Motor_TypeDef* Motor)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  //配置脉冲输出引脚
  GPIO_InitStructure.GPIO_Pin = Motor->Motor_CP_Pin;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(Motor->Motor_CP_GPIOX, &GPIO_InitStructure);
  //配置方向输出引脚
  GPIO_InitStructure.GPIO_Pin = Motor->Motor_DIR_Pin;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(Motor->Motor_DIR_GPIOX, &GPIO_InitStructure);
  //配置使能输出引脚
  GPIO_InitStructure.GPIO_Pin = Motor->Motor_EN_Pin;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(Motor->Motor_EN_GPIOX, &GPIO_InitStructure);
  GPIO_SetBits(Motor->Motor_CP_GPIOX, Motor->Motor_CP_Pin);
  GPIO_SetBits(Motor->Motor_DIR_GPIOX, Motor->Motor_DIR_Pin);
  GPIO_ResetBits(Motor->Motor_EN_GPIOX, Motor->Motor_EN_Pin);
}													 
													 
/**
 * @description: 步进电机0控制初始化
 * @param {*}
 * @return {*}
 */
void Motor0_Init()
{
    Motor0.Motor_CP_CLK = Motor0_CP_CLK;
    Motor0.Motor_CP_GPIOX = Motor0_CP_GPIOX;
    Motor0.Motor_CP_Pin = Motor0_CP_Pin;
    Motor0.Motor_DIR_CLK = Motor0_DIR_CLK;
    Motor0.Motor_DIR_GPIOX = Motor0_DIR_GPIOX;
    Motor0.Motor_DIR_Pin = Motor0_DIR_Pin;
    Motor0.Motor_EN_CLK = Motor0_EN_CLK;
    Motor0.Motor_EN_GPIOX = Motor0_EN_GPIOX;
    Motor0.Motor_EN_Pin = Motor0_EN_Pin;
    Motor0.TIM_MASTER = MOTOR0_MASTER;
    Motor0.TIM_SLAVE = MOTOR0_SLAVE;

    Motor_Cmd(ENABLE);
    Motor_GPIOConfig(&Motor0);
    Tim3Init(1, 1000);
    Tim2Init(2, 300);
}
/**
 * @description: 步进电机1控制初始化
 * @param {*}
 * @return {*}
 */
void Motor1_Init()
{
    Motor1.Motor_CP_CLK = Motor1_CP_CLK;
    Motor1.Motor_CP_GPIOX = Motor1_CP_GPIOX;
    Motor1.Motor_CP_Pin = Motor1_CP_Pin;
    Motor1.Motor_DIR_CLK = Motor1_DIR_CLK;
    Motor1.Motor_DIR_GPIOX = Motor1_DIR_GPIOX;
    Motor1.Motor_DIR_Pin = Motor1_DIR_Pin;
    Motor1.Motor_EN_CLK = Motor1_EN_CLK;
    Motor1.Motor_EN_GPIOX = Motor1_EN_GPIOX;
    Motor1.Motor_EN_Pin = Motor1_EN_Pin;
    Motor1.TIM_MASTER = MOTOR1_MASTER;
    Motor1.TIM_SLAVE = MOTOR1_SLAVE;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
    Motor_GPIOConfig(&Motor1);
    Tim5Init(1, 1000);
    Tim4Init(2, 300);
}
/**
 * @description: 启动或停止电机
 * @param {FunctionalState} NewState：ENABLE/DISABLE
 * @return {*}
 */
void Motor_Start(Motor_TypeDef* Motor,FunctionalState NewState)
{
    if (NewState == ENABLE)
    {
			Motor->Motor_EN_GPIOX->BRR |= Motor->Motor_EN_Pin;
    }
    else
    {
			Motor->Motor_EN_GPIOX->BSRR |= Motor->Motor_EN_Pin;
    }
}

/**
 * @description: 设置步进电机转动方向
 * @param {uint8_t} Dir CCW顺时针 CW逆时针
 * @return {*}
 */
void Motor_SetRotationDirection(Motor_TypeDef* Motor,uint8_t Dir)
{
    if (Dir == CCW)
    {
        Motor->Motor_DIR_GPIOX->BRR |= Motor->Motor_DIR_Pin;
    }
    else
    {
        Motor->Motor_DIR_GPIOX->BSRR |= Motor->Motor_DIR_Pin;
    }
}

void Set_Motor_Speed(TIM_TypeDef *MOTOx, uint16_t psc)
{
    // 也可以使用TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload)修改ARR的值
    MOTOx->PSC = psc;
}
/**
 * @description: 设置输出脉冲个数
 * @param {TIM_TypeDef} *MOTOx
 * @param {uint16_t} pulse_num
 * @return {*}
 */
void Set_Pulse_Num(Motor_TypeDef* Motor, uint16_t pulse_num)
{
    Motor->TIM_SLAVE->ARR = pulse_num;
    TIM_GenerateEvent(Motor->TIM_SLAVE, TIM_EventSource_Update);
    TIM_Cmd(Motor->TIM_SLAVE, ENABLE);
    TIM_Cmd(Motor->TIM_MASTER, ENABLE);
}
/**
 * @description: 使能或失能步进电机控制模块
 * @param {FunctionalState} NewState
 * @return {*}
 */
void Motor_Cmd(FunctionalState NewState)
{
    if (NewState == ENABLE)
    {   
        /*使能TIM2*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        /*使能TIM3*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        /*使能GPIOA*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        /*使能GPIOC*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        // /*使能DMA1*/
        // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    }
    else
    {
        /*失能TIM2*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
        /*失能TIM3*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, DISABLE);
        /*失能GPIOA*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, DISABLE);
        /*失能GPIOC*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, DISABLE);
        /*失能DMA1*/
        //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE);
    }
}

void Motor_DMAConfig(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    /*DMA1 channel 配置*/
    DMA_DeInit(DMA1_Channel2);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM2_ARR_Address;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer_INC;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = BufferSize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

    DMA_Init(DMA1_Channel2, &DMA_InitStructure);

    /* 使能 DMA1 Channel2 传输完成中断 */
    DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);

    /* Enable DMA1 Channel2 */
    DMA_Cmd(DMA1_Channel2, ENABLE);
    

    /* 使能DMA TM2 中断 */
    TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
}


